package org.Yiran.timetale_re.item.tool.chisel.base;

import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.DiggerItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Tier;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.Yiran.timetale_re.Timetale_re;
import org.Yiran.timetale_re.util.item.TooltipUtils;
import org.jetbrains.annotations.NotNull;

import javax.annotation.Nullable;
import java.util.List;

/**
 * 凿子工具基类
 * <p>
 * 该类是所有凿子工具的抽象基类，继承自DiggerItem。
 * 凿子主要用于雕刻和挖掘特定类型的方块，特别是石头类方块。
 * 该类定义了凿子的基本行为，包括挖掘能力、速度、附魔限制等。
 * </p>
 */
public abstract class ChiselItem extends DiggerItem {
    
    // ==============================
    // 常量定义
    // ==============================

    /**
     * 凿子可挖掘方块的标签
     * <p>
     * 定义了哪些方块可以被凿子有效挖掘的标签。
     * 通过ResourceLocation创建自定义标签，标签名为"mineable/chisel"。
     * </p>
     */
    public static final TagKey<Block> MINEABLE_WITH_CHISEL = BlockTags.create(
        ResourceLocation.fromNamespaceAndPath(Timetale_re.MODID, "mineable/chisel")
    );

    // ==============================
    // 构造方法
    // ==============================

    /**
     * 凿子构造函数
     * <p>
     * 创建一个新的凿子实例，设置其材料等级、攻击伤害、攻击速度和物品属性。
     * 默认使用镐可挖掘方块的标签作为基础挖掘能力。
     * </p>
     *
     * @param tier          工具材料等级，定义了耐久度、挖掘速度等属性
     * @param attackDamage  攻击伤害值
     * @param attackSpeed   攻击速度值
     * @param properties    物品属性配置对象
     */
    public ChiselItem(Tier tier, float attackDamage, float attackSpeed, Item.Properties properties) {
        super(attackDamage, attackSpeed, tier, BlockTags.MINEABLE_WITH_PICKAXE, properties);
    }

    // ==============================
    // 挖掘能力方法
    // ==============================

    /**
     * 判断工具是否适合挖掘指定方块
     * <p>
     * 重写父类方法，判断当前凿子是否适合挖掘指定的方块。
     * 凿子可以挖掘石头类方块和标记为可凿子挖掘的方块。
     * </p>
     *
     * @param block 方块状态对象
     * @return 如果适合挖掘返回true，否则返回false
     */
    @Override
    @SuppressWarnings("deprecation")
    public boolean isCorrectToolForDrops(@NotNull BlockState block) {
        // 使用 block.is() 方法检查方块是否属于标签
        return isStoneBlock(block) || block.is(MINEABLE_WITH_CHISEL);
    }

    // ==============================
    // 凿子等级方法
    // ==============================

    /**
     * 获取凿子等级（用于雕刻速度计算）
     * <p>
     * 返回当前凿子的等级，该等级用于计算雕刻速度，数值越高雕刻越快。
     * 等级直接来源于工具材料的等级。
     * </p>
     *
     * @return 凿子等级，数值越高雕刻越快
     */
    @SuppressWarnings("deprecation")
    public int getChiselLevel() {
        return this.getTier().getLevel();
    }

    // ==============================
    // 方块类型判断方法
    // ==============================

    /**
     * 判断是否为石头方块
     * <p>
     * 判断给定的方块是否为石头类方块，包括石头、圆石、苔石、深板岩圆石等。
     * 这些方块可以被凿子有效挖掘。
     * </p>
     *
     * @param block 方块状态对象
     * @return 如果是石头类方块返回true，否则返回false
     */
    private boolean isStoneBlock(BlockState block) {
        return block.is(Blocks.STONE) ||
               block.is(Blocks.COBBLESTONE) ||
               block.is(Blocks.MOSSY_COBBLESTONE) ||
               block.is(Blocks.COBBLED_DEEPSLATE);
    }

    // ==============================
    // 挖掘速度方法
    // ==============================

    /**
     * 获取挖掘速度
     * <p>
     * 重写父类方法，返回使用该凿子挖掘指定方块时的挖掘速度。
     * 对于可有效挖掘的方块返回正常速度，对于其他方块返回极慢的速度。
     * </p>
     *
     * @param stack 凿子物品栈
     * @param state 被挖掘方块的状态
     * @return 挖掘速度值
     */
    @Override
    public float getDestroySpeed(@NotNull ItemStack stack, @NotNull BlockState state) {
        // 如果是石头方块或凿子可挖掘的方块，返回正常的挖掘速度
        if (isCorrectToolForDrops(state)) {
            return super.getDestroySpeed(stack, state);
        }
        // 如果不是凿子可挖掘的方块，返回非常慢地挖掘速度 (降低到0.1F)
        return 0.1F;
    }

    // ==============================
    // 附魔限制方法
    // ==============================

    /**
     * 判断是否可以在附魔台应用指定附魔
     * <p>
     * 重写父类方法，限制凿子可以应用的附魔类型。
     * 禁止时运和精准采集附魔，因为凿子主要用于雕刻而非挖掘获取掉落物。
     * </p>
     *
     * @param stack       凿子物品栈
     * @param enchantment 待应用的附魔
     * @return 如果可以应用该附魔返回true，否则返回false
     */
    @Override
    public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
        // 如果是时运附魔或精准采集附魔，则不允许
        if (enchantment == Enchantments.BLOCK_FORTUNE || enchantment == Enchantments.SILK_TOUCH) {
            return false;
        }
        // 其他附魔保持默认行为
        return super.canApplyAtEnchantingTable(stack, enchantment);
    }

    /**
     * 获取附魔价值
     * <p>
     * 重写父类方法，降低凿子的附魔价值以限制可应用的附魔强度。
     * 返回值比父类低5点，使附魔更加受限。
     * </p>
     *
     * @return 附魔价值
     */
    @Override
    public int getEnchantmentValue() {
        // 返回0以完全禁用附魔，或者返回一个较低的值来限制附魔
        // 我们选择返回一个较低的值，允许其他合适地附魔（如效率等）
        return Math.max(0, super.getEnchantmentValue() - 5);
    }

    // ==============================
    // 客户端显示方法
    // ==============================

    /**
     * 添加物品悬停文本提示
     * <p>
     * 重写父类方法，在物品悬停时显示相关信息。
     * 调用TooltipUtils工具类添加通用的提示信息。
     * </p>
     *
     * @param stack   物品栈
     * @param level   世界对象
     * @param tooltip 提示文本列表
     * @param flag    提示标志
     */
    @Override
    @OnlyIn(Dist.CLIENT)
    public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, @NotNull List<Component> tooltip, @NotNull TooltipFlag flag) {
        super.appendHoverText(stack, level, tooltip, flag);
        // 添加基础描述
        TooltipUtils.addBaseDescription(tooltip, this.getDescriptionId());

        // 隔一行
        TooltipUtils.addSeparatorLine(tooltip);

        // 检查是否按下了Shift键并显示相应信息
        if (TooltipUtils.isShiftPressed()) {
            // 显示详细信息
            TooltipUtils.addDetailedInfo(tooltip, this.getDescriptionId());
        } else {
            // 提示按Shift查看详细信息
            TooltipUtils.addShiftPrompt(tooltip);
        }
    }
}